<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>rpi-image-gen Documentation</title>
    <style>
        body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; max-width: 1200px; margin: 0 auto; padding: 20px; line-height: 1.6; }
        .content { margin-bottom: 40px; }
        .layer-list { margin-bottom: 30px; }
        .layer-item { margin-bottom: 8px; }
        .layer-item a { text-decoration: none; color: #007acc; font-weight: 500; }
        .layer-item a:hover { text-decoration: underline; }
        .layer-desc { color: #666; margin-left: 10px; }
        /* Main content headers styling */
        h1, h2, h3, h4, h5, h6 { color: #333; margin-top: 20px; margin-bottom: 10px; }
        h1 a, h2 a, h3 a, h4 a, h5 a, h6 a { color: #333; text-decoration: none; }
        h3 { color: #000; border-bottom: 1px solid #eee; padding-bottom: 5px; margin-top: 30px; margin-bottom: 15px; }
        /* AsciiDoc table styling */
        .tableblock { border-collapse: collapse; margin: 1.25em 0; table-layout: fixed !important; }
        .tableblock.frame-all { border: 1px solid #dedede; }
        .tableblock.grid-all th, .tableblock.grid-all td { border: 1px solid #dedede; }
        .tableblock.stretch { table-layout: fixed !important; }
        .tableblock.frame-all.grid-all.stretch { table-layout: fixed !important; }
        .tableblock th, .tableblock td { padding: 0.5625em 0.625em; text-align: left; vertical-align: top; }
        .tableblock th { background: #f8f9fa; font-weight: 600; color: rgba(0,0,0,.8); }
        .tableblock tbody tr:nth-child(even) { background: #f8f8f7; }
        .tableblock p { margin: 0; line-height: 1.6; }
        .tableblock .halign-left { text-align: left; }
        .tableblock .halign-center { text-align: center; }
        .tableblock .halign-right { text-align: right; }
        .tableblock .valign-top { vertical-align: top; }
        .tableblock .valign-middle { vertical-align: middle; }
        .tableblock .valign-bottom { vertical-align: bottom; }

        /* Simple code block styling */
        .listingblock pre {
            background: #f8f9fa;
            border: 1px solid #ddd;
            padding: 12px;
            border-radius: 4px;
            overflow-x: auto;
            font-family: monospace;
            font-size: 14px;
        }
        .listingblock pre code {
            background: none;
            border: none;
            padding: 0;
        }

        /* AsciiDoc admonition blocks (NOTE, TIP, WARNING, etc.) */
        .admonitionblock {
            margin: 1.5em 0;
            padding: 0.4em 0.6em;
            border-left: 4px solid;
            background: #f8f9fa;
            border-radius: 0 4px 4px 0;
        }

        .admonitionblock .title {
            font-weight: bold;
            text-transform: uppercase;
            font-size: 0.85em;
            margin-bottom: 0.25em;
            letter-spacing: 0.5px;
        }

        .admonitionblock .content {
            margin: 0;
        }

        /* Reduce spacing for paragraphs inside admonitions */
        .admonitionblock p {
            margin: 0.25em 0;
        }

        .admonitionblock p:first-child {
            margin-top: 0;
        }

        .admonitionblock p:last-child {
            margin-bottom: 0;
        }

        /* Specific admonition types */
        .admonitionblock.note {
            border-color: #17a2b8;
            background: #d1ecf1;
        }

        .admonitionblock.note .title {
            color: #0c5460;
        }

        .admonitionblock.tip {
            border-color: #28a745;
            background: #d4edda;
        }

        .admonitionblock.tip .title {
            color: #155724;
        }

        .admonitionblock.important {
            border-color: #ffc107;
            background: #fff3cd;
        }

        .admonitionblock.important .title {
            color: #856404;
        }

        .admonitionblock.warning,
        .admonitionblock.caution {
            border-color: #dc3545;
            background: #f8d7da;
        }

        .admonitionblock.warning .title,
        .admonitionblock.caution .title {
            color: #721c24;
        }
    </style>
</head>
<body>
    <div class="content">
        <div id="toc" class="toc">
<div id="toctitle">Table of Contents</div>
<ul class="sectlevel1">
<li><a href="#_idp_image_description_provisioning">IDP (Image Description Provisioning)</a>
<ul class="sectlevel2">
<li><a href="#_how_it_works">How it works:</a></li>
<li><a href="#_transport_protocol">Transport Protocol</a></li>
<li><a href="#_json_structure">JSON Structure</a></li>
<li><a href="#_benefits">Benefits:</a></li>
<li><a href="#_dependencies">Dependencies</a></li>
<li><a href="#_usage">Usage:</a></li>
</ul>
</li>
</ul>
</div>
<div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p><a href="../index.html">← Back to Main Documentation</a></p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_idp_image_description_provisioning"><a class="anchor" href="#_idp_image_description_provisioning"></a><a class="link" href="#_idp_image_description_provisioning">IDP (Image Description Provisioning)</a></h2>
<div class="sectionbody">
<div class="paragraph">
<p><strong>IDP</strong> enables secure, flexible device provisioning by bridging rpi-image-gen with <a href="https://github.com/raspberrypi/rpi-sb-provisioner"><strong>rpi-sb-provisioner</strong></a> using a JSON description of your image. IDP supports any partition layout (not just Raspberry Pi OS distribution images) which means it&#8217;s possible to securely provision completely custom images on your Raspberry Pi device.</p>
</div>
<div class="sect2">
<h3 id="_how_it_works"><a class="anchor" href="#_how_it_works"></a><a class="link" href="#_how_it_works">How it works:</a></h3>
<div class="olist arabic">
<ol class="arabic">
<li>
<p><strong>Generate</strong> - rpi-image-gen creates an image description JSON file</p>
</li>
<li>
<p><strong>Send</strong> - Client transfers the description to device</p>
</li>
<li>
<p><strong>Validate</strong> - Device verifies compatibility (model, storage requirements, security attributes)</p>
</li>
<li>
<p><strong>Prepare</strong> - Device creates partition tables, LUKS containers, etc.</p>
</li>
<li>
<p><strong>Provision</strong> - Client writes partition images to prepared block devices</p>
</li>
</ol>
</div>
<div class="paragraph">
<p>IDP acts as a "smart block device creation tool" that prepares device storage and orchestrates secure image deployment through a defined protocol.</p>
</div>
</div>
<div class="sect2">
<h3 id="_transport_protocol"><a class="anchor" href="#_transport_protocol"></a><a class="link" href="#_transport_protocol">Transport Protocol</a></h3>
<div class="paragraph">
<p>IDP was designed to be transport medium agnostic. The current implementation uses fastboot as the transport protocol, which allows it to interoperate with devices running the <a href="https://github.com/raspberrypi/pi-gen-micro"><strong>pi-gen-micro</strong></a> fastboot gadget.</p>
</div>
</div>
<div class="sect2">
<h3 id="_json_structure"><a class="anchor" href="#_json_structure"></a><a class="link" href="#_json_structure">JSON Structure</a></h3>
<div class="paragraph">
<p>The image description is split into two components using a simple schema:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><strong>Image layout</strong> - partition table and individual image information, sizes, filesystem types, attributes, metadata</p>
</li>
<li>
<p><strong>Provisioning map (PMAP)</strong> - defines how the image will be provisioned on-device, e.g. partitions to encrypt, security attributes to use</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>If an image layer is to support IDP, it must declare support of a provisioning map in its config settings and install the applicable JSON fragment as <code>${IGconf_image_outputdir}/provisionmap.json</code>. Typically this is handled by image layer specific hooks. If installed, rpi-image-gen will automatically include the PMAP in the final image description file (<code>image.json</code>). Please refer to the individual layer documentation for available PMAP options.</p>
</div>
</div>
<div class="sect2">
<h3 id="_benefits"><a class="anchor" href="#_benefits"></a><a class="link" href="#_benefits">Benefits:</a></h3>
<div class="ulist">
<ul>
<li>
<p><strong>Smart provisioning</strong> - Device validates before writing</p>
</li>
<li>
<p><strong>Flexible layouts</strong> - Support custom partition schemes</p>
</li>
<li>
<p><strong>Encryption support</strong> - Integrates with LUKSv2, signed boot and industry standard encryption flows</p>
</li>
<li>
<p><strong>Secure workflow</strong> - Validation at every step</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="_dependencies"><a class="anchor" href="#_dependencies"></a><a class="link" href="#_dependencies">Dependencies</a></h3>
<div class="paragraph">
<p>IDP requires fastboot to be installed in the client. On Debian systems, this can be installed using <code><code>sudo apt install fastboot</code></code>. Sparse format images are used when writing to device storage and rpi-image-gen image layers create sparse images by default using genimage. This avoids reliance on any external tooling, such as AOSP utilities. Using sparse format means images with lots of empty space can be transferred and written to device storage in a much shorter time using fastboot when compared with primitive tools such as dd. Other utilities such as bmaptool provide a similar, much-improved way for storage handling and IO transfer.</p>
</div>
<div class="admonitionblock warning">
<table>
<tr>
<td class="icon">
<div class="title">Warning</div>
</td>
<td class="content">
<div class="paragraph">
<p>Raspberry Pi provisioning tools such as <code>rpi-sb-provisioner</code> (<a href="https://github.com/raspberrypi/rpi-sb-provisioner" class="bare">https://github.com/raspberrypi/rpi-sb-provisioner</a>) rely on sparse images, so rpi-image-gen ships its own up-to-date <code>genimage</code> to avoid compatibility problems seen with older distribution versions.</p>
</div>
</td>
</tr>
</table>
</div>
</div>
<div class="sect2">
<h3 id="_usage"><a class="anchor" href="#_usage"></a><a class="link" href="#_usage">Usage:</a></h3>
<div class="paragraph">
<p>To use IDP <strong>without</strong> rpi-sb-provisioner:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>Become familiar with <strong>rpiboot</strong> (<a href="https://github.com/raspberrypi/usbboot" class="bare">https://github.com/raspberrypi/usbboot</a>)</p>
</li>
<li>
<p>Build the pi-gen-micro fastboot gadget (<a href="https://github.com/raspberrypi/pi-gen-micro" class="bare">https://github.com/raspberrypi/pi-gen-micro</a>)</p>
</li>
<li>
<p>Boot the fastboot gadget on the target device</p>
</li>
<li>
<p>From your client, provision your image on the target device using rpi-image-gen&#8217;s helper:</p>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-bash" data-lang="bash">$ ./bin/idp.sh -f /path/to/image.json</code></pre>
</div>
</div>
</li>
</ol>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<div class="title">Note</div>
</td>
<td class="content">
<div class="paragraph">
<p>It&#8217;s also possible to issue conventional fastboot commands from the client to the device. For example, to write a sparse image to device storage:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-bash" data-lang="bash">$ fastboot flash mmcblk0 /path/to/fullimage.sparse</code></pre>
</div>
</div>
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>rpi-sb-provisioner will gain support for IDP which will enable seamless integration and secure deployment of rpi-image-gen created images on your Raspberry Pi device. Refer to the <a href="https://github.com/raspberrypi/rpi-sb-provisioner"><strong>rpi-sb-provisioner</strong> documentation</a> for further details.</p>
</div>
</div>
</div>
</div>

    </div>

    
</body>
</html>